﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using BMS.Syncro.Devices.Configuration.Interfaces;
using BMS.Syncro.Devices.Message;
using BMS.Syncro.Devices.Persister.Interfaces;
using BMS.Syncro.Devices.Utility;
using log4net;
using zkemkeeper;

namespace BMS.Syncro.Devices.Persister
{
    public class DefaultZKEMPersister : ISyncroMessagePersister
    {
        #region Properties
        private readonly ILog _log = null;
        private ZKEMDeviceUtil _utility;
        // Class for the biometric device
        private CZKEMClass Device;
        #endregion Properties

        #region Methods

        /// <summary>
        /// Constructor method
        /// </summary>
        public DefaultZKEMPersister()
        {
            // Create a instance of the device management
            Device = new CZKEMClass();

            _log = LogManager.GetLogger(this.GetType());
        }

        #region IPersister<T> Members

        public string PersisterInvokeBy
        {
            get { return this.GetType().Name; }
        }

        public DateTime WhenInvoke
        {
            get { return DateTime.Now; }
        }

        /// <summary>
        /// Save a message in a specific device
        /// </summary>
        /// <param name="message">Message to save in the device</param>
        /// <returns></returns>
        public bool Save(SyncroMessage message)
        {
            try
            {
                // Connect with the specific device
                Device.Connect_Net(message.Device.IpAddress, int.Parse(message.Device.Port));
                // Disable the device
                Device.EnableDevice(Device.MachineNumber, false);
            }
            catch
            {
                throw new InvalidCastException(string.Format("El tipo de dato para la ip o el puerto es inválido, por favor valide la configuración. Ip configurada: [{0}], puerto configurado: [{1}]", message.Device.IpAddress, message.Device.Port));
            }

            try
            {
                _log.Debug(string.Format("Guardando la información en el dispositivo biométrico: {0}", message.Device.IpAddress));
                // Begining the process to save the user in the specific device
                if (Device.SSR_SetUserInfo(Device.MachineNumber, message.Visitor.IdNumberBiometricDevice, message.Visitor.FullName, message.Visitor.Password, 0, true))
                {
                    // Begining the process to save the fingerprint for that user in the specific device
                    if (Device.SetUserTmpExStr(Device.MachineNumber, message.Visitor.IdNumberBiometricDevice, int.Parse(message.Visitor.FingerIndex), 0, message.Visitor.FingerPrint))
                        _log.Debug(string.Format("Información almacenada en el dispositivo biométrico {0} de manera satisfactoria", message.Device.IpAddress));
                    else
                        _log.Debug(string.Format("No fue posible realizar la creación de la huella en el dispositivo biométrico {0}. Detalle del evento: {1}", message.Device.IpAddress, _utility.GetErrorMessageFromDevice(Device)));
                }
                else
                    _log.Debug(string.Format("No fue posible realizar la creación del usuario del dispositivo biométrico {0}. Detalle del evento: {1}", message.Device.IpAddress, _utility.GetErrorMessageFromDevice(Device)));
            }
            catch
            {
                throw new Exception(string.Format("No fue posible almacenar la información en el dispositivo biométrico: {0}", message.Device.IpAddress));
            }
            finally
            { 
                // Refresh the data informatio in the specific biometric device
                Device.RefreshData(Device.MachineNumber);
                // Enable the device
                Device.EnableDevice(Device.MachineNumber, true);
                // Disconect with the specific device
                Device.Disconnect();
            }

            return true;
        }


        /// <summary>
        /// Update a message in a specific device
        /// </summary>
        /// <param name="message">Message to update in the device</param>
        /// <returns></returns>
        public bool Update(SyncroMessage message)
        {
            return this.Save(message);
        }

        /// <summary>
        /// Delete a message from a specific device
        /// </summary>
        /// <param name="message">Message to delete from the device</param>
        /// <returns></returns>
        public bool Delete(SyncroMessage message)
        {
            try
            {
                // Connect with the specific device
                Device.Connect_Net(message.Device.IpAddress, int.Parse(message.Device.Port));
                // Disable the device
                Device.EnableDevice(Device.MachineNumber, false);
            }
            catch
            {
                throw new InvalidCastException(string.Format("El tipo de dato para la ip o el puerto es inválido, por favor valide la configuración. Ip configurada: [{0}], puerto configurado: [{1}]", message.Device.IpAddress, message.Device.Port));
            }

            try
            {

                _log.Debug(string.Format("Eliminando la información del dispositivo biométrico: {0}", message.Device.IpAddress));
                // Begining the process for delete the user in the specific device
                if (Device.SSR_DelUserTmp(Device.MachineNumber, message.Visitor.IdNumberBiometricDevice, int.Parse(message.Visitor.FingerIndex)))
                    _log.Debug(string.Format("Información eliminada del dispositivo biométrico {0} de manera satisfactoria", message.Device.IpAddress));
                else
                    _log.Debug(string.Format("No fue posible realizar la eliminación de la huella del dispositivo biométrico {0}. Detalle del evento: {1}", message.Device.IpAddress, _utility.GetErrorMessageFromDevice(Device)));
            }
            catch
            {
                throw new Exception(string.Format("No fue posible eliminar la información del dispositivo biométrico: {0}", message.Device.IpAddress));
            }
            finally
            {
                // Refresh the data informatio in the specific biometric device
                Device.RefreshData(Device.MachineNumber);
                // Enable the device
                Device.EnableDevice(Device.MachineNumber, true);
                // Disconect with the specific device
                Device.Disconnect();
            }

            return true;
        }

        #endregion

        #endregion Methods
    }
}
